package com.night.student.service.impl;

import com.night.common.entity.administration.Course;
import com.night.common.entity.administration.CourseManager;
import com.night.common.entity.administration.Teacher;
import com.night.common.entity.student.*;
import com.night.student.mapper.EvaluateMapper;
import com.night.student.mapper.LessonMapper;
import com.night.student.mapper.ScoreMapper;
import com.night.student.service.LessonService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Time;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Mr.Wang
 * @ClassName: LessonServiceImpl
 * @Description: //TODO
 * @date: 2022/10/21-11:53
 */
@Service
public class LessonServiceImpl implements LessonService {
    @Autowired
    LessonMapper lessonMapper;
    @Autowired
    ScoreMapper scoreMapper;
    @Autowired
    EvaluateMapper evaluateMapper;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    //根据学生id查所选课程
    @Override
    public List<CourseManager>[] getCourseByStudent(int studentId,int classId) {
        //从redis、mysql拿到班级必修课
        List<CourseManager> classCourse = getClassCourse(classId);
        //根据学生id查选修，可能为空
        List<CourseManager> studentCourse = lessonMapper.getCourseByStudentId(studentId);
        //按照星期几的课进行合并
        int studentCourseSize = studentCourse==null ? 0:studentCourse.size();
        List<CourseManager> totalCourse = new ArrayList<>(classCourse.size()+studentCourseSize);
        for (CourseManager course : classCourse) {
            totalCourse.add(course);
        }
        if(studentCourse!=null && studentCourseSize!=0){
            for (CourseManager course : studentCourse) {
                totalCourse.add(course);
            }
        }
        return sortByWeek(totalCourse);
    }

    //进行选课
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean SelectCourse(SelectCourseVo selectCourseVo) {
        String key = "stu"+selectCourseVo.getStudentId()+"co"+selectCourseVo.getCourseManagerId();
        if(redisTemplate.hasKey(key)){
            return false;
        }else{
            redisTemplate.opsForValue().set(key,1,10,TimeUnit.SECONDS);
        }
        if(redisTemplate.opsForHash().hasKey("student"+selectCourseVo.getStudentId(),String.valueOf(selectCourseVo.getCourseManagerId())))
            return false;
        if(!isTimeConflict(selectCourseVo.getClassId(),selectCourseVo.getCourseWeek(),selectCourseVo.getCourseStartTime(),selectCourseVo.getCourseEndTime()))
            return false;
        int i = lessonMapper.updateNum(selectCourseVo.getCourseManagerId());
        if(i==0){
            return false;
        }
        rabbitTemplate.convertAndSend("exchangetopic", "afterselect", selectCourseVo);
        return true;
    }

    private List<CourseManager>[] sortByWeek(List<CourseManager> courses){
        String[] days = new String[]{"一","二","三","四","五","六","日"};
        List<CourseManager>[] result = new ArrayList[7];
        for (int i = 0; i < 7; i++) {
            List<CourseManager> oneDay = new ArrayList<>();
            for (int j = 0; j < courses.size(); j++) {
                if(("周"+days[i]).equals(courses.get(j).getCourseWeek())){
                    oneDay.add(courses.get(j));
                }
            }
            result[i]=oneDay;
        }
        return result;
    }
    //查询选中选修课程时间是否与必修冲突
    public Boolean isTimeConflict(int classId, String courseWeek,Time startTime,Time endTime) {
        List<CourseManager> classCourse = getClassCourse(classId);
        for (int j = 0; j < classCourse.size(); j++) {
            if(courseWeek.equals(classCourse.get(j).getCourseWeek())){
                if(!(startTime.after(classCourse.get(j).getCourseEndTime()) || endTime.before(classCourse.get(j).getCourseStartTime()))){
                    return false;
                }
            }
        }
        return true;
    }

    //得到必修课
    private List<CourseManager> getClassCourse(int id){
        String classId = String.valueOf(id);
        List<CourseManager> classCourse =(List<CourseManager>)redisTemplate.opsForHash().get(classId,classId);
        if(classCourse == null){
            classCourse = lessonMapper.getCourseByCondition(id);
            redisTemplate.opsForHash().put(classId, classId,classCourse);
            if(classCourse != null){
                redisTemplate.expire(classId,45,TimeUnit.MINUTES);
            }else{
                redisTemplate.expire(classId,3,TimeUnit.MINUTES);
            }
        }
        return classCourse;
    }


    //选课后操作
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void executeAfterSelectLesson(SelectCourseVo selectCourseVo) {
        //1.向学生选课表中增加记录
        lessonMapper.insert(selectCourseVo.getStudentId(),selectCourseVo.getCourseManagerId());
        //2.向成绩表中增加初始记录
        Score score = new Score();
        Student student = new Student();
        student.setId(selectCourseVo.getStudentId());
        score.setStudent(student);
        CourseManager course = new CourseManager();
        course.setId(selectCourseVo.getCourseManagerId());
        score.setCourse(course);
        score.setTerm(selectCourseVo.getTerm());
        score.setCredit(selectCourseVo.getCourseCredit());
        scoreMapper.insert(score);
        //3.向评价表中增加初始记录
        Evaluate evaluate = new Evaluate();
        Teacher teacher = new Teacher();
        teacher.setId(selectCourseVo.getTeacherId());
        evaluate.setTeacher(teacher);
        evaluate.setStudent(student);
        Course course1 = new Course();
        course1.setId(selectCourseVo.getCourseId());
        evaluate.setCourse(course1);
        evaluate.setTerm(selectCourseVo.getTerm());
        evaluate.setStatus("n");
        evaluateMapper.insert(evaluate);

        redisTemplate.opsForHash().put("student"+selectCourseVo.getStudentId(),String.valueOf(selectCourseVo.getCourseManagerId()),1);
        redisTemplate.expire("student"+selectCourseVo.getStudentId(),1,TimeUnit.DAYS);
    }
}
